package ru.ibrae.excelparser1.mainlogics.constructors;

import java.util.ArrayList;
import jxl.Cell;
import jxl.DateCell;
import jxl.LabelCell;
import jxl.NumberCell;
import jxl.Sheet;
import jxl.Workbook;

import jxl.read.biff.BiffException;

import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;

import jxl.write.biff.RowsExceededException;

import ru.ibrae.excelparser1.excelstorageentities.constructionresults.CommonInfoConstructionResult;
import ru.ibrae.excelparser1.excelstorageentities.constructionresults.VerificationResult;
import ru.ibrae.excelparser1.excelstorageentities.entities.CommonInfo;
import ru.ibrae.excelparser1.excelstorageentities.entities.MessageLevel;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;

import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import ru.ibrae.excelparser1.excelstorageentities.entities.MyExcelCell;
import ru.ibrae.excelparser1.mainlogics.config.ConfigurationWorker;
import ru.ibrae.excelparser1.mainlogics.fileworkers.FileNameParser.FileNameVerificaionResult;


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author murr
 */
public class CommoinInfoConstructor {

    private final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
    //~ Methods ----------------------------------------------------------------

    static CommonInfoConstructionResult constructCommonInfo(File fileToRead,
            Integer lastRow, FileNameVerificaionResult verificaionResult)
            throws IOException,
            BiffException {
        CommonInfo commonInfo = null;
        Workbook workbook = null;
        VerificationResult result = new VerificationResult("",
                MessageLevel.NO_ERRORS);
        workbook = Workbook.getWorkbook(fileToRead);

        Sheet sheet1 = workbook.getSheet(0);
        Sheet sheet2 = workbook.getSheet(1);
        Date beginning = null;
        Date end = null;
        Date creationDate = null;
        String okato = "";
        String ogrn = "";
        String shortName = "";
        String fullName = "";
        Integer rowCount = null;

        if (!sheet1.getCell(1, 6).getContents().equals("")) {
            if (sheet1.getCell(1, 6) instanceof DateCell) {
                DateCell dateCell = (DateCell) sheet1.getCell(1, 6);
                beginning = dateCell.getDate();
                if (!DATE_FORMAT.format(beginning).equals(DATE_FORMAT.format(verificaionResult.getFileNameInfo().getStart()))) {
                    result.setMessage("Дата начала в файле не совпадает с датой начала в названии файла.");
                    result.setMessageLevel(MessageLevel.FILE_FATAL);
                    return new CommonInfoConstructionResult(result, null);
                }
            }
        } else {
            result.setMessage("Не задана дата начала");
            result.setMessageLevel(MessageLevel.FILE_FATAL);
            return new CommonInfoConstructionResult(result, null);
        }

        if (!sheet1.getCell(1, 7).getContents().equals("")) {
            if (sheet1.getCell(1, 7) instanceof DateCell) {
                DateCell dateCell = (DateCell) sheet1.getCell(1, 7);
                end = dateCell.getDate();
                if (!DATE_FORMAT.format(end).equals(DATE_FORMAT.format(verificaionResult.getFileNameInfo().getEnd()))) {
                    result.setMessage("Дата конца в файле не совпадает с датой конца в названии файла.");
                    result.setMessageLevel(MessageLevel.FILE_FATAL);
                    return new CommonInfoConstructionResult(result, null);
                }
            }
        } else {
            result.setMessage("Не задана дата конца");
            result.setMessageLevel(MessageLevel.FILE_FATAL);

            return new CommonInfoConstructionResult(result, null);
        }

        if (end.before(beginning)) {
            result.setMessage(
                    "Неправильный период: конец раньше начала\nОбработка файла прервана");
            result.setMessageLevel(MessageLevel.FILE_FATAL);

            return new CommonInfoConstructionResult(result, null);
        }

        if (!sheet1.getCell(1, 9).getContents().equals("")) {
            if (sheet1.getCell(1, 9) instanceof DateCell) {
                DateCell dateCell = (DateCell) sheet1.getCell(1, 9);
                creationDate = dateCell.getDate();
            }
        } else {
            result.setMessage(
                    ( result.getMessageLevel() == MessageLevel.FILE_NON_FATAL )
                    ? ( result.getMessage() + "\n"
                    + "Не задана дата создания" )
                    : "Не задана дата создания");
            result.setMessageLevel(MessageLevel.FILE_NON_FATAL);
        }

        if (!sheet1.getCell(1, 3).getContents().equals("")) {
            okato = sheet1.getCell(1, 3).getContents();
        } else {
            result.setMessage(
                    ( result.getMessageLevel() == MessageLevel.FILE_NON_FATAL )
                    ? ( result.getMessage() + "\n"
                    + "Не задан ОКАТО" ) : "Не задан ОКАТО");
            result.setMessageLevel(MessageLevel.FILE_NON_FATAL);
        }

        if (!sheet1.getCell(1, 2).getContents().equals("")) {
            ogrn = sheet1.getCell(1, 2).getContents();

            if (ogrn.length() != 13) {
                result.setMessageLevel(MessageLevel.FILE_FATAL);
                result.setMessage("Неправильно задан ОГРН");
                return new CommonInfoConstructionResult(result, null);
            } else {
                try {
                    Long valueOf = Long.valueOf(ogrn);
                    if (!ogrn.equalsIgnoreCase(verificaionResult.getFileNameInfo().getOgrn())) {
                        result.setMessageLevel(MessageLevel.FILE_FATAL);
                        result.setMessage("ОГРН в файле не совпадает с ОГРН в названии файла");
                        return new CommonInfoConstructionResult(result, null);
                    }
                }
                catch (Exception e) {
                    result.setMessageLevel(MessageLevel.FILE_FATAL);
                    result.setMessage("Неправильно задан ОГРН");

                    return new CommonInfoConstructionResult(result, null);
                }
            }
        } else {
            result.setMessageLevel(MessageLevel.FILE_FATAL);
            result.setMessage("Не задан ОГРН");

            return new CommonInfoConstructionResult(result, null);
        }

        if (!sheet1.getCell(1, 0).getContents().equals("")) {
            if (sheet1.getCell(1, 0) instanceof LabelCell) {
                LabelCell labelCell = (LabelCell) sheet1.getCell(1, 0);
                fullName = labelCell.getString();
            }
        } else {
            String text = "Не задано краткое название организации";
            result.setMessage(
                    ( result.getMessageLevel() == MessageLevel.FILE_NON_FATAL )
                    ? ( result.getMessage() + "\n" + text ) : text);
            result.setMessageLevel(MessageLevel.FILE_NON_FATAL);
        }

        if (!sheet1.getCell(1, 1).getContents().equals("")) {
            if (sheet1.getCell(1, 1) instanceof LabelCell) {
                LabelCell labelCell = (LabelCell) sheet1.getCell(1, 1);
                shortName = labelCell.getString();
            }
        } else {
            String text = "Не задано полное название организации";
            result.setMessage(
                    ( result.getMessageLevel() == MessageLevel.FILE_NON_FATAL )
                    ? ( result.getMessage() + "\n" + text ) : text);
            result.setMessageLevel(MessageLevel.FILE_NON_FATAL);
        }

        if (!sheet1.getCell(1, 10).getContents().equals("")) {
            if (sheet1.getCell(1, 10) instanceof NumberCell) {
                NumberCell numberCell = (NumberCell) sheet1.getCell(1, 10);
                rowCount = Double.valueOf(numberCell.getValue()).intValue();

                int realRowCount = lastRow - 1;

                if (realRowCount != rowCount) {
                    String text = "Неправильно задано количество строк на втором листе";
                    result.setMessage(
                            ( result.getMessageLevel() == MessageLevel.FILE_NON_FATAL )
                            ? ( result.getMessage() + "\n"
                            + text ) : text);
                    result.setMessageLevel(MessageLevel.FILE_NON_FATAL);
                    Corrector.writeCorrectRowCount(realRowCount, fileToRead);
                }
            }
        } else {
            String text = "Не указано количество строк на втором листе";
            result.setMessage(
                    ( result.getMessageLevel() == MessageLevel.FILE_NON_FATAL )
                    ? ( result.getMessage() + "\n" + text ) : text);
            result.setMessageLevel(MessageLevel.FILE_NON_FATAL);
            Corrector.writeCorrectRowCount(lastRow - 2, fileToRead);
        }
        boolean correctStructure = verifySheet2Structure(sheet2);
        if (!correctStructure) {
            result.setMessage("11  - УПО: критическая ошибка данных. Неверная структура файла данных");
            result.setMessageLevel(MessageLevel.FILE_FATAL);
            return new CommonInfoConstructionResult(result, null);
        }

        commonInfo = new CommonInfo(beginning,
                end,
                creationDate,
                okato,
                ogrn,
                shortName,
                fullName,
                rowCount);

        return new CommonInfoConstructionResult(result, commonInfo);
    }

    private static boolean verifySheet2Structure(Sheet s) throws IOException {
        ArrayList<MyExcelCell> correctCells = ConfigurationWorker.getCorrectList2Header();
        for (MyExcelCell myExcelCell : correctCells) {
            Cell cell = s.getCell(myExcelCell.getCol(), myExcelCell.getRow());
            if (!cell.getContents().equalsIgnoreCase(myExcelCell.getContent()) || !cell.getType().toString().equalsIgnoreCase(myExcelCell.getCellType())) {
                return false;
            }
        }
        return true;
    }

    //~ Inner Classes ----------------------------------------------------------
    private static class Corrector {

        private static void writeCorrectRowCount(Integer rowCount,
                File fileToRead) {
            try {
                Workbook w = Workbook.getWorkbook(
                        fileToRead);
                WritableWorkbook writableWorkbook = Workbook.createWorkbook(
                        fileToRead,
                        w);
                WritableSheet writableSheet = writableWorkbook.getSheet(0);
                jxl.write.Number n = new jxl.write.Number(1,
                        10,
                        rowCount);
                writableSheet.addCell(n);
                writableWorkbook.write();
                writableWorkbook.close();
            }
            catch (RowsExceededException ex) {
                Logger.getLogger(CommoinInfoConstructor.class.getName()).log(
                        Level.SEVERE,
                        null,
                        ex);
            }
            catch (WriteException ex) {
                Logger.getLogger(CommoinInfoConstructor.class.getName()).log(
                        Level.SEVERE,
                        null,
                        ex);
            }
            catch (IOException ex) {
                Logger.getLogger(CommoinInfoConstructor.class.getName()).log(
                        Level.SEVERE,
                        null,
                        ex);
            }
            catch (BiffException ex) {
                Logger.getLogger(CommoinInfoConstructor.class.getName()).log(
                        Level.SEVERE,
                        null,
                        ex);
            }
        }
    }
}
